package com.xrh.core.bean;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;

import com.xrh.core.enums.CompareType;
import com.xrh.core.exceptions.BusinessException;
import com.xrh.core.interfaces.ParseQueryerInf;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

@Data
public class Queryer {
	
	@ApiModelProperty("要查询的列名")
	private String colName;
	
	/*
	 * 列表与要比较的值是否相当还是模糊查询
	 */
	@ApiModelProperty("比较类型枚举)")
	private CompareType compareType;

	@ApiModelProperty("要比较的值，in查询用逗号隔开")
	private String compareValue;
	
	@ApiModelProperty("是否and下一个查询条件,不是and则为or")
	private boolean andNextQueryer = true;
	
	@ApiModelProperty("后续链接的查询条件") 
	private Queryer nextQueryer;
	
	@ApiModelProperty("复合查询条件集合")
	private List<Queryer> complexQueryerList;
	
	@ApiModelProperty("升序降序字段")
	private List<OrderByInfo> orderByList;
	
	@ApiModelProperty("要返回的字段")
	private List<String> selectColumnNames;
	
	@ApiModelProperty("要分组的字段")
	private List<String> groupByColumnNames;
	
	@ApiModelProperty("having表示式集合")
	private List<String> havingExpressions;
	
	/**
	 * @function having表达式 , 放到group by后面
	 * @param expressions
	 * @author 肖荣辉
	 * @date 2023年8月10日
	*/
	public void having(String... expressions) {
		
		List<String> havingExpressions  = new ArrayList<String>();
		
		for(String item : expressions) {
			havingExpressions.add(item);
		}
		
		this.havingExpressions = havingExpressions;
	}
	
	/**
	 * @function 要分组的字段
	 * @param columnNames
	 * @author 肖荣辉
	 * @date 2023年8月10日
	*/
	public void groupBy(String... columnNames) {
		
		List<String> groupByColumnNames  = new ArrayList<String>();
		
		for(String item : columnNames) {
			groupByColumnNames.add(item);
		}
		
		this.groupByColumnNames = groupByColumnNames;
	}
	
	/**
	 * @function 查询语句要返回的字段
	 * @param columnNames
	 * @author 肖荣辉
	 * @date 2023年1月31日
	 */
	public void select(String... columnNames) {
		this.selectColumnNames = CollUtil.newArrayList(columnNames);
	}
	
	/**
	 * @function 多个字段升序
	 * @param columnNames 多个要排序的字段
	 * @author 肖荣辉
	 * @date 2023年1月31日
	*/
	public void orderByAsc(String... columnNames) {
		
		List<OrderByInfo> orderByList  = new ArrayList<OrderByInfo>();
		
		for(String item : columnNames) {
			orderByList.add(new OrderByInfo(item, true));
		}
		
		this.orderByList = orderByList;
	}
	
	/**
	 * @function 多个字段降序
	 * @param columnNames 多个要排序的字段
	 * @author 肖荣辉
	 * @date 2023年1月31日
	*/
	public void orderByDesc(String... columnNames) {
		
		List<OrderByInfo> orderByList  = new ArrayList<OrderByInfo>();
		
		for(String item : columnNames) {
			orderByList.add(new OrderByInfo(item, false));
		}
		
		this.orderByList = orderByList;
	}
	
	/**
	 * @function 多个字段排序
	 * @param orderByInfos 多个要排序的字段信息
	 * @author 肖荣辉
	 * @date 2023年1月31日
	*/
	public void orderBy(OrderByInfo... orderByInfos) {
		
		List<OrderByInfo> orderByList  = new ArrayList<OrderByInfo>();
		
		for(OrderByInfo item : orderByInfos) {
			orderByList.add(item);
		}
		
		this.orderByList = orderByList;
	}
	
	/**
	 * @function 切换为or下一个条件
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer or() {
		Queryer last = getLastQueryer(this);
		last.andNextQueryer = false;
		return this;
	}
	

	/**
	 * @function  找到最后的那个查询条件
	 * @author 肖荣辉
	 * @date 2022年12月9日
	 */
	public Queryer getLastQueryer(Queryer queryer) {
		
		if(queryer.getNextQueryer() != null)
			return getLastQueryer(queryer.getNextQueryer());
		
		return queryer;
	}
	
	
	/**
	 * @function 是否是一个空的查询器
	 * @param Queryer
	 * @author 肖荣辉
	 * @date 2022年12月9日
	 */
	public boolean isEmpty() {
		return StrUtil.isBlank(colName) && nextQueryer == null;
	}
	
	/**
	 * @function 是否史一个空的查询器
	 * @param Queryer
	 * @author 肖荣辉
	 * @date 2022年12月9日
	 */
	public boolean isEmptyQueryer(Queryer Queryer) {
		return Queryer == null || StrUtil.isBlank(colName);
	}
	
	/**
	 * @function  链接下一个条件
	 * @param linkNextQueryer
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	private Queryer linkNextQueryer(String colName , String compareValue , CompareType compareType) {
		
		if(StrUtil.isBlank(colName))
			throw new BusinessException("列名不能为空");
		
		Queryer queryer =  getLastQueryer(this);
		
		if(StrUtil.isNotBlank(queryer.getColName())) {
			
			Queryer temp = new Queryer();
			
			queryer.nextQueryer = temp;
			
			queryer = temp;
			
		}
		
		queryer.colName = colName;
		queryer.compareType = compareType;
		queryer.compareValue = compareValue;
		
		return this;
		
	}
	
	/**
	 * @function 等值比较
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer eq(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue , CompareType.EQ);
	}
	
	/**
	 * @function  in查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer in(String colName , Collection<String> compareValue) {
		return linkNextQueryer(colName , StrUtil.join(",", new HashSet<String>(compareValue)) , CompareType.IN );
	}
	
	
	/**
	 * @function  not in查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer notIn(String colName , Collection<String> compareValue) {
		return linkNextQueryer(colName , StrUtil.join(",", new HashSet<String>(compareValue)) , CompareType.NOT_IN );
	}
	
	/**
	 * @function  大于查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer gt(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue , CompareType.GT );
	}
	
	/**
	 * @function  小于查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer lt(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue , CompareType.LT );
	}
	
	/**
	 * @function  大于等于查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer ge(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue , CompareType.GE );
	}
	
	/**
	 * @function  小于等于查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer le(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue , CompareType.LE );
	}
	
	/**
	 * @function  不等于
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer ne(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue , CompareType.NE );
	}
	
	/**
	 * @function  like查询 , compareValue默认前后加上百分号%%
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer like(String colName , String compareValue) {
		return linkNextQueryer(colName , "%" + compareValue + "%" , CompareType.LIKE );
	}
	
	/**
	 * @function  like前缀模糊查询 , compareValue前面加上百分号%
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer preLike(String colName , String compareValue) {
		return linkNextQueryer(colName , "%" + compareValue , CompareType.LIKE );
	}
	
	/**
	 * @function  like词尾模糊查询 , compareValue后面加上百分号%
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer suffixLike(String colName , String compareValue) {
		return linkNextQueryer(colName , compareValue + "%" , CompareType.LIKE );
	}
	
	/**
	 * @function  isNull查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer isNull(String colName) {
		return linkNextQueryer(colName , null , CompareType.IS_NULL );
	}
	
	/**
	 * @function  isNotNull查询
	 * @param colName 要查询的字段
	 * @param compareValue 要查询的值
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer isNotNull(String colName) {
		return linkNextQueryer(colName , null , CompareType.IS_NOT_NULL );
	}
	
	/**
	 *  加一个复杂的查询条件
	 * @param queryer
	 * @author 肖荣辉
	 * @date 2022年12月12日
	 */
	public Queryer and(Queryer complexQueryer) {
		
		if(complexQueryer == null)
			return this;
		
		Queryer queryer =  getLastQueryer(this);
		
		if(StrUtil.isBlank(queryer.getColName())) {
			BeanUtil.copyProperties(complexQueryer , this);
			return this;
		}
		
		Queryer last = getLastQueryer(this);
		
		last.complexQueryerList  = last.complexQueryerList == null ? new ArrayList<Queryer>() : last.complexQueryerList;
		
		last.complexQueryerList.add(complexQueryer);
		
		return this;
	}
	
	/**
	 * @function 根据解析器解析出对应的查询语句
	 * @param parseQueryerInf
	 * @author 肖荣辉paQueryerInf
	 * @date 2022年12月12日
	 */
	public String parseQueryer(ParseQueryerInf parseQueryerInf) {
		return parseQueryerInf.parseQueryer(this);
	}
	
}
